package com.xw.service.impl;

import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xw.common.Constants;
import com.xw.dao.*;
import com.xw.entity.*;
import com.xw.exp.ServiceException;
import com.xw.rep.LoginRep;
import com.xw.req.LoginReq;
import com.xw.req.PageRequest;
import com.xw.service.MenuService;
import com.xw.service.OperationLogService;
import com.xw.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.excel.EasyExcel;
import com.xw.entity.User;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
 * @Description: 针对表【user】的数据库操作Service实现
 * @Author: 72478
 * @Date: 2024/12/18 16:53
 * @Version: 1.0
 */
@Service
public class UserServiceImpl implements UserService {
    public static final String ROLE_ADMIN = "ROLE_ADMIN";
    @Resource
    private UserDao userDao;

    @Resource
    private UserTokenDao userTokenDao;

    @Resource
    private MenuService menuService;

    @Resource
    private RolesDao rolesDao;

    @Resource
    private OperationLogService operationLogService;

    /**
     * 根据角色名称获取相关用户列表
     * @param roleName 角色名称
     * @return 相关用户列表
     */
    public List<User> getUsersByRole(String roleName) {
        return userDao.findUsersByRole(roleName);
    }

    @Override
    public Boolean register(User user) {
        // 校验密码一致性
        if (!user.getPassword().equals(user.getConfirmPassword())) {
            throw new ServiceException(Constants.ERROR.getCode(), "两次密码输入不一样");
        }

        // 校验用户名是否存在
        User userQuery = new User();
        userQuery.setUserName(user.getUserName());
        List<User> users = userDao.selectAll(userQuery);
        if (!CollectionUtils.isEmpty(users)) {
            throw new ServiceException(Constants.ERROR.getCode(), "用户已存在");
        }

        // 校验邮箱是否已注册
        User userQueryEmail = new User();
        userQueryEmail.setEmail(user.getEmail());
        List<User> usersEmailList = userDao.selectAll(userQueryEmail);
        Optional<User> _find = usersEmailList.stream()
                .filter(u -> u.getEmail().equals(user.getEmail()))
                .findAny();
        if (_find.isPresent()) {
            throw new ServiceException(Constants.ERROR.getCode(), "邮箱已注册");
        }
        // 如果头像为空，设置默认图片地址
        if (user.getImageUrl() == null || user.getImageUrl().isEmpty()) {
            user.setImageUrl("https://img2.baidu.com/it/u=2625169353,2769422191&fm=253&fmt=auto?w=800&h=800");
        }

        // 使用前端传来的已加密 MD5 密码，直接保存
        userDao.insert(user);

        // 创建注册日志
        OperationLog log = new OperationLog();
        // 操作描述
        log.setOperation("用户注册");
        // 操作时间
        log.setOperationTime(new Date());
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        // 获取 IP 地址
        log.setIpAddress(getIpAddress(request));

        // 设置用户ID
        log.setUserId(5L);

        // 保存注册日志
        operationLogService.saveOperationLog(log);

        return true;
    }


    private String getIpAddress(HttpServletRequest request) {
        String ipAddress = request.getHeader("X-Forwarded-For");
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        return ipAddress;
    }

    @Override
    @Transactional
    public LoginRep login(LoginReq loginReq) {
        User userQuery = new User();
        userQuery.setUserName(loginReq.getUserName());
        userQuery.setPassword(loginReq.getPassword());
        User user = userDao.selectByUserNameAndPassword(userQuery);

        if (Objects.isNull(user)) {
            throw new ServiceException(Constants.UNAUTHORIZED.getCode(),"用户不存在或用户密码错误");
        }

        LoginRep loginRep = new LoginRep();
        loginRep.setUserId(user.getId());
        loginRep.setNickName(user.getNickName());
        loginRep.setImageUrl(user.getImageUrl());
        long time = new Date().getTime();
        String token = DigestUtil.md5Hex(user.getId() + "_" + time);
        loginRep.setToken(token);
        loginRep.setRole(user.getRole());

        Roles roles = rolesDao.selectByRoleName(user.getRole());
        loginRep.setRoleRemark(roles.getRemark());

        // 在新增token之前把该用户的老得token删掉
        UserToken userTokenQuery =  userTokenDao.selectByUserId(user.getId());
        if (Objects.nonNull(userTokenQuery)) {
            userTokenDao.deleteById(userTokenQuery.getId());
        }

        // 把数据新增到 userToken 表
        UserToken userToken = new UserToken();
        userToken.setUserId(user.getId());
        userToken.setToken(token);
        // 默认永不过期
        userToken.setOverdue(-1);
        userToken.setCreateTime(new Date());
        userTokenDao.insert(userToken);

        // 判断登陆的用户是什么角色
        List<Menu> menus = new ArrayList<>();
        if (user.getRole().equals("ROLE_ADMIN")) {
            menus = menuService.menuList();
        } else {
            menus = menuService.menuListByRoleName(user.getRole());
        }
        loginRep.setMenuList(menus);
        return loginRep;
    }

    @Override
    public PageInfo<User> page(PageRequest<User> pageRequest) {
        PageHelper.startPage(pageRequest.getPageNum(),pageRequest.getPageSize());
        List<User> users = userDao.selectAll(pageRequest.getQ());
        PageInfo<User> pageInfo = new PageInfo<>(users);
        return pageInfo;
    }
    @Override
    public List<User> listAllUsers() {
        return userDao.selectAll(null);  // 直接调用dao层的selectAll方法获取所有用户数据，传入null表示无查询条件筛选
    }

    @Override
    public void importUsers(List<User> userList) {
        List<String> existingEmails = new ArrayList<>();
        for (User user : userList) {
            User existingUser = userDao.findByEmail(user.getEmail());
            if (existingUser != null) {
                // 如果邮箱已经存在，记录下该邮箱
                existingEmails.add(user.getEmail());
                continue;  // 跳过插入此用户
            }

            user.setNickName(user.getUserName());
            // 密码默认设置为 123456，加密后保存
            user.setPassword("123456");
            user.setPassword(DigestUtil.md5Hex(user.getPassword()));
            user.setImageUrl("https://img2.baidu.com/it/u=2625169353,2769422191&fm=253&fmt=auto?w=800&h=800");
            userDao.insert(user);
        }

        if (!existingEmails.isEmpty()) {
            // 如果有已经存在的邮箱，抛出包含所有已存在邮箱的异常
            throw new ServiceException(Constants.ERROR.getCode(), "以下邮箱已存在，跳过插入该用户：" + String.join(", ", existingEmails));
        }
    }


}